/* File:  scanner.l
 * ----------------
 * Lex inupt file to generate the scanner for the compiler.
 */

%{

/* The text within this first region delimited by %{ and %} is assumed to
 * be C/C++ code and will be copied verbatim to the lex.yy.c file ahead
 * of the definitions of the yylex() function. Add other header file inclusions
 * or C++ variable declarations/prototypes that are needed by your code here.
 */

#include <string.h>
#include "scanner.h"
#include "utility.h" // for PrintDebug()
#include "location.h"
#include "parser.h" // for token codes
//#include "errors.h"

/* Global variable: yylval
 * -----------------------
 * This global variable is how we get attribute information about the token
 * just scanned to the client. The scanner sets the global variable
 * appropriately and since it's global the client can just read it.  In the
 * future, this variable will be declared for us in the y.tab.c file
 * produced by Yacc, but for now, we declare it manually.
 */
//YYSTYPE yylval;  // manually declared for pp1, later Yacc provides

/* Global variable: yylloc
 * -----------------------
 * This global variable is how we get position information about the token
 * just scanned to the client. (Operates similarly to yylval above)
 */
struct yyltype yylloc; // manually dclared for pp1, later Yacc provides

/* Macro: YY_USER_ACTION 
 * ---------------------
 * This flex built-in macro can be defined to provide an action which is
 * always executed prior to any matched rule's action. Basically, it is
 * a way of having a piece of code common to all actions factored out to
 * this routine.  We already defined it for you and left the empty
 * function DoBeforeEachAction ready for your use as needed. It will
 * be called once for each pattern scanned from the file, before
 * executing its action.
 */
static void DoBeforeEachAction(); 
#define YY_USER_ACTION DoBeforeEachAction();

int line_num; int cols;
%}

 /* The section before the first %% is the Definitions section of the lex
  * input file. Here is where you set options for the scanner, define lex
  * states, and can set up definitions to give names to regular expressions
  * as a simple substitution mechanism that allows for more readable
  * entries in the Rules section later. 

badString	\"[^\"\n]*"\n"
  */

letter		[a-z]
digit		[0-9]
integer		{digit}+
name		[a-z][a-z0-9]*
literal		\"[^\"\n]*\"		

%%             /* BEGIN RULES SECTION */
 /* All patterns and actions should be placed between the start and stop
  * %% markers which delimit the Rules section. 
  */ 

"INT"						return T_Int;
"STR20"						return T_String;

"create"|"CREATE"			return T_Create; 
"drop"|"DROP"				return T_Drop;
"select"|"SELECT"			return T_Select;
"delete"|"DELETE"			return T_Delete;
"insert"|"INSERT"			return T_Insert;
"into"|"INTO"				return T_Into;
"table"|"TABLE"				return T_Table;
"distinct"|"DISTINCT"		return T_Distinct;
"from"|"FROM"				return T_From;
"where"|"WHERE"				return T_Where;
"order"|"ORDER"				return T_Order;
"by"|"BY"					return T_By;
"values"|"VALUES"			return T_Values;
"NULL"						return T_Null;
"NOT"						return T_Not;
"AND"						return T_And;
"OR"						return T_Or;
"<"							return T_Less;
">"							return T_Greater;
"="							return T_Equal;

"+"|"-"|"*"|"/"		{
							return *yytext;
					}
"("|")"|"["|"]"|"{"|"}"	{
							return *yytext;
						}
","|"."					{
							return *yytext;
						}
{integer}		{
					yylval.intConstant = atoi(yytext);	
					return T_IntConstant;
				}
{name}			{
					//printf("Name: %s\n", yytext); 
					strcpy(yylval.identifier, yytext);
					return T_Name;
				}
{literal}		{
					//printf("Literal: %s\n", yytext); 
					yylval.stringConstant = yytext;
					return T_StringConstant;
				}
" "|"\t"		
\n			{
				++line_num;			
				cols = 1;	
				return T_LineEnd;
			}
.			{
				printf("Unrecognized Char: %c\n", *yytext);
	          //ReportError::UnrecogChar(&yylloc, *yytext);	
			}

%%
/* The closing %% above marks the end of the Rules section and the beginning
 * of the User Subroutines section. All text from here to the end of the
 * file is copied verbatim to the end of the generated lex.yy.c file.
 * This section is where you put definitions of helper functions.
 */


/* Function: InitScanner
 * ---------------------
 * This function will be called before any calls to yylex().  It is designed
 * to give you an opportunity to do anything that must be done to initialize
 * the scanner (set global variables, configure starting state, etc.). One
 * thing it already does for you is assign the value of the global variable
 * yy_flex_debug that controls whether flex prints debugging information
 * about each token and what rule was matched. If set to false, no information
 * is printed. Setting it to true will give you a running trail that might
 * be helpful when debugging your scanner. Please be sure the variable is
 * set to false when submitting your final version.
 */
void InitScanner()
{
    PrintDebug("lex", "Initializing scanner");
    yy_flex_debug = false;
    line_num = 1;
    cols = 1;
}


/* Function: DoBeforeEachAction()
 * ------------------------------
 * This function is installed as the YY_USER_ACTION. This is a place
 * to group code common to all actions.
 */
static void DoBeforeEachAction()
{
	yylloc.first_line = line_num;
	yylloc.last_line  = line_num;
	yylloc.first_column = cols;
	cols += yyleng;
	yylloc.last_column = cols-1;
}
